/*
 * @FileName: mppt.h
 * @Author: GreyQiu qiushaogui@aikosolar.com
 * @Date: 2023-07-21 11:51:27
 * @LastEditors: GreyQiu qiushaogui@aikosolar.com
 * @LastEditTime: 2023-09-06 16:01:36
 * @Description: 
 * 
 * Copyright (c) 2023, All Rights Reserved. 
 */

#ifndef __MPPT_H__
#define __MPPT_H__

#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include "easy_pid_f32.h"

#define MPPT_VOC_OFFSET (-0.5f)

typedef enum {
    MPPT_STATE_DISABLE = 0, // 禁止
    MPPT_STATE_TRACK,       // 追踪
    MPPT_STATE_DELAY,       // 延迟
    MPPT_STATE_BYPASS,      // 直通
} mppt_state_t;

/**
 * @description: mppt对象定义
 */
typedef struct 
{
    uint16_t id;        // mppt的id
    uint16_t div;       // MPPT分频
    uint16_t state;     // mppt状态
    uint16_t cnt_step;      // 用于变步长
    uint16_t cnt_delay;      // 用于MPP点延时和直通延时
    uint16_t cnt_prescale; // 用于MPP运行分频计数

    int8_t dir[2];      // 记录历史4次的扰动方向，用于判断是否找到MPPT点

    float pwr_pre;      // 上一步的功率值

    float step;         // 扰动步长
    float stepMax;      // 最大扰动步长
    float stepMin;      // 最小扰动步长
    float stepGrad;     // 变步长时的渐变幅度

    float out;          // mppt输出
    float outMax;       // 最大mppt输出
    float outMin;       // 最小mppt输出

    float voc;          // 组件开路电压

    float * vin_addr;   // MPPT的输入电压源地址
    float * iin_addr;   // MPPT的输入电流源地址
    easy_integral_f32_t * loop; // MPPT环路对象地址
    bool find_mpp;      // 找到MPP点标志
} mppt_t;

void mppt_handle(mppt_t * mppt);
void mppt_reset(mppt_t * mppt);
#endif // __MPPT_H__
